﻿using System;
using System.Collections.Generic;
using System.Linq;
using Gumini.JulaDB.Enums;
using Gumini.JulaDB.Provider;

namespace Gumini.JulaDB.Expressions
{
    /// <summary>
    /// A string => T mapping class used for evaluating types and values of an expression.
    /// </summary>
    public class Context<T>
    {
        private readonly Dictionary<string, List<T>> _valueMapping = new Dictionary<string, List<T>>();
        private readonly static Context<T> _empty = new Context<T>();

        public void Add(string key, T value)
        {
            string lowercaseKey = key.ToLowerInvariant();
            if (!_valueMapping.ContainsKey(lowercaseKey))
                _valueMapping[lowercaseKey] = new List<T>();
            _valueMapping[lowercaseKey].Add(value);
        }

        public T this[string key]
        {
            get
            {
                string lowercaseKey = key.ToLowerInvariant();
                if (!_valueMapping.ContainsKey(lowercaseKey))
                    throw new JulaDbException(ErrorCode.UnknownIdentifier, "Identifier '{0}' is unknown.", key);
                else if (_valueMapping[lowercaseKey].Count > 1)
                    throw new JulaDbException(ErrorCode.AmbiguousIdentifier, "Identifier '{0}' is ambiguous.", key);
                return _valueMapping[lowercaseKey].Single();
            }
        }

        public bool ContainsKey(string key)
        {
            string lowercaseKey = key.ToLowerInvariant();
            return _valueMapping.ContainsKey(lowercaseKey);
        }

        public static Context<T> Empty
        {
            get { return _empty; }
        }

        public override string ToString()
        {
            return String.Format("Count: {0}");
        }
    }
}
